﻿// Copyright 2001-2010 - Active Up SPRLU (http://www.agilecomponents.com)
//
// Data Connection Suite is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.

// Data Connection Suite is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.

// You should have received a copy of the GNU General Public License along with
// Data Connection Suite. If not, see http://www.gnu.org/licenses/.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MySql.Data.MySqlClient;

namespace AgileComponents.DataConnection
{
    /// <summary>
    /// 
    /// </summary>
    public partial class MySqlDataConnectionControl : DataConnectionControl
    {
        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="MySqlDataConnectionControl"/> class.
        /// </summary>
        public MySqlDataConnectionControl()
        {
            InitializeComponent();

            this.Builder = new MySqlConnectionStringBuilder();
        }

        #endregion

        #region Event Handler

        /// <summary>
        /// Handles the Click event of the testConnectionButton control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void testConnectionButton_Click(object sender, EventArgs e)
        {
            this.TestConnectionString(this.serverNamesComboBox.Text);
        }

        /// <summary>
        /// Handles the Click event of the databasesComboBox control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void databasesComboBox_Click(object sender, EventArgs e)
        {
            if (!DatabaseListCreated && !DatabaseListCreating)
                this.GetDatabase();
        }

        /// <summary>
        /// Handles the KeyUp event of the serverNamesComboBox control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Forms.KeyEventArgs"/> instance containing the event data.</param>
        private void serverNamesComboBox_KeyUp(object sender, KeyEventArgs e)
        {
            DatabaseListCreated = false;
            if (!string.IsNullOrEmpty(this.serverNamesComboBox.Text) &&
                this.connectToDatabaseGroupBox.Enabled == false)
                this.connectToDatabaseGroupBox.Enabled = true;
        }

        /// <summary>
        /// Handles the Click event of the advancedButton control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void advancedButton_Click(object sender, EventArgs e)
        {
            ConnectionStringPropertiesDialog dialog = new ConnectionStringPropertiesDialog(this.Builder);
            dialog.ShowDialog();

            PopulateForm();
        }

        /// <summary>
        /// Handles the TextChanged event of the serverNamesComboBox control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void serverNamesComboBox_TextChanged(object sender, EventArgs e)
        {
            this.RaiseDataConnectionChanged();
        }

        /// <summary>
        /// Handles the ValueChanged event of the portNumericUpDown control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void portNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            this.RaiseDataConnectionChanged();
        }

        /// <summary>
        /// Handles the TextChanged event of the usernameTextBox control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void usernameTextBox_TextChanged(object sender, EventArgs e)
        {
            this.RaiseDataConnectionChanged();
        }

        /// <summary>
        /// Handles the TextChanged event of the passwordTextBox control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void passwordTextBox_TextChanged(object sender, EventArgs e)
        {
            this.RaiseDataConnectionChanged();
        }

        /// <summary>
        /// Handles the TextChanged event of the databasesComboBox control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void databasesComboBox_TextChanged(object sender, EventArgs e)
        {
            this.RaiseDataConnectionChanged();
        }

        #endregion

        #region Implementations

        /// <summary>
        /// Gets the connection.
        /// </summary>
        /// <returns></returns>
        public override IDbConnection GetConnection()
        {
            return new MySqlConnection(this.ConnectionString);
        }


        /// <summary>
        /// Gets or sets the connection string.
        /// </summary>
        /// <value>The connection string.</value>
        public override string ConnectionString
        {
            get
            {
                PopulateBuilder();
                return base.ConnectionString;
            }
            set
            {
                base.ConnectionString = value;
                PopulateForm();
            }
        }

        /// <summary>
        /// Populates the builder.
        /// </summary>
        private void PopulateBuilder()
        {
            MySqlConnectionStringBuilder builder = (MySqlConnectionStringBuilder)Builder;

            builder.Server = this.serverNamesComboBox.Text;

            builder.UserID = this.usernameTextBox.Text;
            builder.Password = this.passwordTextBox.Text;

            if (this.portNumericUpDown.Value != 3306)
                builder.Port = (uint)this.portNumericUpDown.Value;

            builder.Database = this.databasesComboBox.Text;
        }

        /// <summary>
        /// Populates the form.
        /// </summary>
        private void PopulateForm()
        {
            MySqlConnectionStringBuilder builder = (MySqlConnectionStringBuilder)Builder;

            this.serverNamesComboBox.Text = builder.Server;

            this.usernameTextBox.Text = builder.UserID;
            this.passwordTextBox.Text = builder.Password;

            this.portNumericUpDown.Value = builder.Port;

            this.databasesComboBox.Text = builder.Database;
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Gets the database.
        /// </summary>
        private void GetDatabase()
        {
            try
            {
                this.databasesComboBox.Items.Clear();
                this.databasesComboBox.Items.Add("Please wait while loading available schemas...");
                DataTable tables = new DataTable("Tables");
                using (MySqlConnection connection = new MySqlConnection(this.ConnectionString))
                {
                    MySqlCommand command = connection.CreateCommand();
                    command.CommandText = "SELECT * FROM INFORMATION_SCHEMA.SCHEMATA";
                    connection.Open();
                    tables.Load(command.ExecuteReader(CommandBehavior.CloseConnection));
                }
                this.databasesComboBox.Items.Clear();
                foreach (DataRow row in tables.Rows)
                    this.databasesComboBox.Items.Add(row[1].ToString());
            }
            catch (MySqlException)
            {
                this.databasesComboBox.Items.Clear();
                this.databasesComboBox.Items.Add("Connection error. Check server & credentials");
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error while loading available schemas: " + ex.ToString());
            }
            finally
            {
                DatabaseListCreating = false;
            }
        }

        #endregion
    }
}
